package com.rundatop.core.util; 
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.math.BigInteger;
import java.nio.charset.Charset;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;  

/** 
 * @ClassName:     FileSplitMergeUtil 
 * @Description:	文件分隔合并相关
 * @author:    翟鑫
 * @date:        2018年1月29日 下午5:32:42  
 */ 

public class FileSplitMergeUtil {
	 /** 
     * 文件分割 
     * @param src 源文件路径 
     * @param fileSize 分割后每个文件的大小，单位是MB 
     * @param dest 目标文件路径 
     */  
    public static void split(String src,int fileSize,String dest){  
          
        if("".equals(src)||src==null||fileSize==0||"".equals(dest)||dest==null){  
            System.out.println("分割失败");  
        }  
          
        File srcFile = new File(src);//源文件  
          
        long srcSize = srcFile.length();//源文件的大小  
        long destSize = 1024*1024*fileSize;//目标文件的大小（分割后每个文件的大小）  
          
        int number = (int)(srcSize/destSize);  
        number = srcSize%destSize==0?number:number+1;//分割后文件的数目  
          
        String fileName = src.substring(src.lastIndexOf("\\"));//源文件名  
          
        InputStream in = null;//输入字节流  
        BufferedInputStream bis = null;//输入缓冲流  
        byte[] bytes = new byte[1024*1024];//每次读取文件的大小为1MB  
        int len = -1;//每次读取的长度值  
        try {  
            in = new FileInputStream(srcFile);  
            bis = new BufferedInputStream(in);  
            for(int i=0;i<number;i++){  
                  
                String destName = dest+File.separator+getFileNameNoEx(fileName)+"-"+i+"."+getExtensionName(srcFile.getName());  
                OutputStream out = new FileOutputStream(destName);  
                BufferedOutputStream bos = new BufferedOutputStream(out);  
                int count = 0;  
                while((len = bis.read(bytes))!=-1){  
                    bos.write(bytes, 0, len);//把字节数据写入目标文件中  
                    count+=len;  
                    if(count>=destSize){  
                        break;  
                    }  
                }  
                bos.flush();//刷新  
                bos.close();  
                out.close();  
            }  
        } catch (FileNotFoundException e) {  
            e.printStackTrace();  
        } catch (IOException e) {  
            e.printStackTrace();  
        }finally{  
            //关闭流  
            try {  
                if(bis!=null)bis.close();  
                if(in!=null)in.close();  
            } catch (IOException e) {  
                e.printStackTrace();  
            }  
        }  
    }  
      
    /** 
     * 文件合并 
     * 注意：在拼接文件路劲时，一定不要忘记文件的跟路径，否则复制不成功 
     * @param destPath 目标目录 
     * @param srcPaths 源文件目录 
     */  
    public static boolean merge(String destPath,String extName,String ... srcPaths){
        if(destPath==null||"".equals(destPath)||srcPaths==null){  
            System.out.println("合并失败");  
        }  
        for (String string : srcPaths) {  
            if("".equals(string)||string==null)  
                System.out.println("合并失败");  
        }  
        //合并后的文件名  
        System.out.println(srcPaths[0].lastIndexOf("/"));
        String name = srcPaths[0].substring(srcPaths[0].lastIndexOf("/"));  
        String destName = name.substring(0, name.lastIndexOf("_"))+"."+extName;  
        destPath = destPath+destName;//合并后的文件路径  
          
        File destFile = new File(destPath);//合并后的文件  
        OutputStream out = null;  
        BufferedOutputStream bos = null;  
        try {  
            out = new FileOutputStream(destFile);  
            bos = new BufferedOutputStream(out);  
            for (String src : srcPaths) {  
                File srcFile = new File(src);  
                InputStream in = new FileInputStream(srcFile);  
                BufferedInputStream bis = new BufferedInputStream(in);  
                byte[] bytes = new byte[1024*1024];  
                int len = -1;  
                while((len = bis.read(bytes))!=-1){  
                    bos.write(bytes, 0, len);  
                }  
                bis.close();  
                in.close();  
            }
            return true;
        } catch (FileNotFoundException e) {  
            e.printStackTrace();  
        } catch (IOException e) {  
            e.printStackTrace();  
        }finally{  
            //关闭流  
            try {  
                if(bos!=null)bos.close();  
                if(out!=null)out.close();  
            } catch (IOException e) {  
                e.printStackTrace();  
            }  
        }  
        return false;
    }  
	/**
	 * Java文件操作 获取文件扩展名
	 */
	public static String getExtensionName(String filename) {
		if ((filename != null) && (filename.length() > 0)) {
			int dot = filename.lastIndexOf('.');
			if ((dot > -1) && (dot < (filename.length() - 1))) {
				return filename.substring(dot + 1);
			}
		}
		return filename.toLowerCase();
	}
	/**
	 * Java文件操作 获取不带扩展名的文件名
	 */
	public static String getFileNameNoEx(String filename) {
		if ((filename != null) && (filename.length() > 0)) {
			int dot = filename.lastIndexOf('.');
			if ((dot > -1) && (dot < (filename.length()))) {
				return filename.substring(0, dot);
			}
		}
		return filename.toLowerCase();
	}
    /**
     * 删除空目录
     * @param dir 将要删除的目录路径
     */
	public static void doDeleteEmptyDir(String dir) {
        boolean success = (new File(dir)).delete();
        if (success) {
            System.out.println("Successfully deleted empty directory: " + dir);
        } else {
            System.out.println("Failed to delete empty directory: " + dir);
        }
    }

    /**
     * 递归删除目录下的所有文件及子目录下所有文件
     * @param dir 将要删除的文件目录
     * @return boolean Returns "true" if all deletions were successful.
     *                 If a deletion fails, the method stops attempting to
     *                 delete and returns "false".
     */
    public static boolean deleteDir(File dir) {
        if (dir.isDirectory()) {
            String[] children = dir.list();
            //递归删除目录中的子目录下
            for (int i=0; i<children.length; i++) {
                boolean success = deleteDir(new File(dir, children[i]));
                if (!success) {
                    return false;
                }
            }
        }
        // 目录此时为空，可以删除
        return dir.delete();
    }
    /**
     * 删除单个文件
     *
     * @param fileName
     *            要删除的文件的文件名
     * @return 单个文件删除成功返回true，否则返回false
     */
    public static boolean deleteFile(String fileName) {
        File file = new File(fileName);
        // 如果文件路径所对应的文件存在，并且是一个文件，则直接删除
        if (file.exists() && file.isFile()) {
            if (file.delete()) {
                //System.out.println("删除单个文件" + fileName + "成功！");
                return true;
            } else {
                //System.out.println("删除单个文件" + fileName + "失败！");
                return false;
            }
        } else {
            //System.out.println("删除单个文件失败：" + fileName + "不存在！");
            return false;
        }
    }
	public static String getMD5(String path) {
		BigInteger bi = null;
		try {
			byte[] buffer = new byte[8192];
			int len = 0;
			MessageDigest md = MessageDigest.getInstance("MD5");
			File f = new File(path);
			FileInputStream fis = new FileInputStream(f);
			while ((len = fis.read(buffer)) != -1) {
				md.update(buffer, 0, len);
			}
			fis.close();
			byte[] b = md.digest();
			bi = new BigInteger(1, b);
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return bi.toString(16);
	}
	
	
	public static void downFileZip(String[] srcFiles, HttpServletResponse response) throws IOException{

        ServletOutputStream sos = response.getOutputStream();
        ZipOutputStream zos = new ZipOutputStream(sos, Charset.forName("UTF-8"));
        FileInputStream in = null;
        
        //设置压缩比0-9,0-9，速度变慢，压缩质量变高，设置个2，3左右即可。
        zos.setLevel(2);
//        zos.setEncoding("UTF-8");
        byte[] buf = new byte[1024];
        for (String file : srcFiles) {
            File entryFile = new File(file);
            in = new FileInputStream(entryFile);
            ZipEntry zipEntry = new ZipEntry(file.substring(file.lastIndexOf("\\")+1)); 
            zos.putNextEntry(zipEntry);
            int len;
            while ((len = in.read(buf)) > 0) {
                zos.write(buf, 0, len);
            }
            zos.closeEntry();
        }
        zos.flush();
        zos.close();
        in.close();
        sos.close();
        
    }
    public static void main(String[] args) {  
        /** 
         * 分割测试 
         */  
//      String src = "D:\\test/test.pdf";//要分割的大文件  
//      int fileSize = 30;  
//      String dest = "D:\\";      //文件分割后保存的路径  
//      System.out.println("分割开始。。。");  
//      split(src, fileSize, dest);  
//      System.out.println("分割完成");  
          
        /** 
         * 合并测试 
         */  
        //合并后文件的保存路径  
       /* String destPath = "D:\\upan";  
        //要合并的文件路径  
        String[] srcPaths = {  
                "D:\\JDK_API_1_6_zh_CN.CHM-0.dat",  
                "D:\\JDK_API_1_6_zh_CN.CHM-1.dat",  
                "D:\\JDK_API_1_6_zh_CN.CHM-2.dat",  
                "D:\\JDK_API_1_6_zh_CN.CHM-3.dat"};  
        System.out.println("开始合并。。。");  
        merge(destPath, srcPaths);  
        System.out.println("合并结束");  */
      System.out.println(getMD5("D:\\test/test.pdf"));
      System.out.println(getMD5("D:\\test/test-0.pdf"));
      System.out.println(getMD5("D:\\test/test-1.pdf"));
      System.out.println(getMD5("D:\\test/test-2.pdf"));
      
      
    }  
}
 
